/*
    * Copyright (c) 2024 Hunan OpenValley Digital Industry Development Co., Ltd.
    * Licensed under the Apache License, Version 2.0 (the "License");
    * you may not use this file except in compliance with the License.
    * You may obtain a copy of the License at
    *
    *     http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing, software
    * distributed under the License is distributed on an "AS IS" BASIS,
    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    * See the License for the specific language governing permissions and
    * limitations under the License.
 */

#ifndef FILE_SHARE_JSON_UTIL_H
#define FILE_SHARE_JSON_UTIL_H

#include "file_share_common.h"
#include "nlohmann/json.hpp"

using json = nlohmann::json;

namespace OHOS {
namespace FileShare {
inline void fileInfoToJson(const FileInfo& fileInfo, nlohmann::json& jsonObject) 
{
    jsonObject[SIZE_KEY] = fileInfo.size;
    jsonObject[PATH_KEY] = fileInfo.path;
    jsonObject[NAME_KEY] = fileInfo.name;
    jsonObject[HASH_KEY] = fileInfo.hash;
    jsonObject[UTD_KEY] = fileInfo.utd;
    jsonObject[URI_KEY] = fileInfo.uri;
    jsonObject[ORIG_FILE_NAME_KEY] = fileInfo.origFileName;
    jsonObject[NEW_FILE_NAME_KEY] = fileInfo.newFileName;
    jsonObject[RECV_PATH] = fileInfo.recvPath;
}

inline void JsonToFileInfo(const nlohmann::json& jsonObject, FileInfo& fileInfo)
{
    if (jsonObject.find(SIZE_KEY) != jsonObject.end() && jsonObject.at(SIZE_KEY).is_number()) {
        fileInfo.size = jsonObject.at(SIZE_KEY).get<int>();
    }
    if (jsonObject.find(NAME_KEY) != jsonObject.end() && jsonObject.at(NAME_KEY).is_string()) {
        fileInfo.name = jsonObject.at(NAME_KEY).get<std::string>();
    }
    if (jsonObject.find(PATH_KEY) != jsonObject.end() && jsonObject.at(PATH_KEY).is_string()) {
        fileInfo.path = jsonObject.at(PATH_KEY).get<std::string>();
    }
    if (jsonObject.find(HASH_KEY) != jsonObject.end() && jsonObject.at(HASH_KEY).is_string()) {
        fileInfo.hash = jsonObject.at(HASH_KEY).get<std::string>();
    }
    if (jsonObject.find(UTD_KEY) != jsonObject.end() && jsonObject.at(UTD_KEY).is_string()) {
        fileInfo.utd = jsonObject.at(UTD_KEY).get<std::string>();
    }
    if (jsonObject.find(URI_KEY) != jsonObject.end() && jsonObject.at(URI_KEY).is_string()) {
        fileInfo.uri = jsonObject.at(URI_KEY).get<std::string>();
    }
    if (jsonObject.find(ORIG_FILE_NAME_KEY) != jsonObject.end() && jsonObject.at(ORIG_FILE_NAME_KEY).is_string()) {
        fileInfo.origFileName = jsonObject.at(ORIG_FILE_NAME_KEY).get<std::string>();
    }
    if (jsonObject.find(NEW_FILE_NAME_KEY) != jsonObject.end() && jsonObject.at(NEW_FILE_NAME_KEY).is_string()) {
        fileInfo.newFileName = jsonObject.at(NEW_FILE_NAME_KEY).get<std::string>();
    }
    if (jsonObject.find(RECV_PATH) != jsonObject.end() && jsonObject.at(RECV_PATH).is_string()) {
        fileInfo.recvPath = jsonObject.at(RECV_PATH).get<std::string>();
    }
}

inline void SendTaskToJson(const SendTask& sendTask, nlohmann::json& jsonObject) 
{
    nlohmann::json jsonFiles = nlohmann::json::array();
    for (auto file : sendTask.files) {
        nlohmann::json jsonFile;
        fileInfoToJson(file, jsonFile);
        jsonFiles.push_back(jsonFile);
    }
    jsonObject[FILES_KEY] = jsonFiles;
    jsonObject[DEVICE_ID_KEY] = sendTask.deviceId;
    jsonObject[NETWORK_ID_KEY] = sendTask.networkId;
    jsonObject[DEVICE_NAME_KEY] = sendTask.deviceName;
    jsonObject[SHARE_TYPE_KEY] = (int) sendTask.type;
    jsonObject[FOLDER_NAME_KEY] = sendTask.folderName;
}

inline void JsonToSendTask(const nlohmann::json& jsonObject, SendTask& task)
{
    if (jsonObject.find(DEVICE_ID_KEY) != jsonObject.end() && jsonObject.at(DEVICE_ID_KEY).is_string()) {
        task.deviceId = jsonObject.at(DEVICE_ID_KEY).get<std::string>();
    }
    if (jsonObject.find(NETWORK_ID_KEY) != jsonObject.end() && jsonObject.at(NETWORK_ID_KEY).is_string()) {
        task.networkId = jsonObject.at(NETWORK_ID_KEY).get<std::string>();
    }
    if (jsonObject.find(DEVICE_NAME_KEY) != jsonObject.end() && jsonObject.at(DEVICE_NAME_KEY).is_string()) {
        task.deviceName = jsonObject.at(DEVICE_NAME_KEY).get<std::string>();
    }
    if (jsonObject.find(SHARE_TYPE_KEY) != jsonObject.end() && jsonObject.at(SHARE_TYPE_KEY).is_number()) {
        task.type = (ShareType) jsonObject.at(SHARE_TYPE_KEY).get<int>();
    }
    if (jsonObject.find(FOLDER_NAME_KEY) != jsonObject.end() && jsonObject.at(FOLDER_NAME_KEY).is_string()) {
        task.folderName = jsonObject.at(FOLDER_NAME_KEY).get<std::string>();
    }

    if (jsonObject.find(FILES_KEY) != jsonObject.end() && jsonObject.at(FILES_KEY).is_array()) {
        for (const auto& fileJson : jsonObject.at(FILES_KEY)) {
            FileInfo file;
            JsonToFileInfo(fileJson, file);
            task.files.push_back(file);
        }
    }
}

inline void SendInfoToJson(const SendInfo& sendInfo, nlohmann::json& jsonObject) 
{
    nlohmann::json jsonFiles = nlohmann::json::array();
    for (auto file : sendInfo.files) {
        nlohmann::json jsonFile;
        fileInfoToJson(file, jsonFile);
        jsonFiles.push_back(jsonFile);
    }
    jsonObject[FILES_KEY] = jsonFiles;
    jsonObject[PROGRESS_KEY] = sendInfo.progress;
    jsonObject[SHARE_TYPE_KEY] = (int) sendInfo.type;
    jsonObject[SPEED_KEY] = sendInfo.speed;
}

inline void JsonToSendInfo(const nlohmann::json& jsonObject, SendInfo& sendInfo)
{
    if (jsonObject.find(PROGRESS_KEY) != jsonObject.end() && jsonObject.at(PROGRESS_KEY).is_number()) {
        sendInfo.progress = jsonObject.at(PROGRESS_KEY).get<int>();
    }
    if (jsonObject.find(SHARE_TYPE_KEY) != jsonObject.end() && jsonObject.at(SHARE_TYPE_KEY).is_number()) {
        sendInfo.type = (ShareType) jsonObject.at(SHARE_TYPE_KEY).get<int>();
    }
    if (jsonObject.find(SPEED_KEY) != jsonObject.end() && jsonObject.at(SPEED_KEY).is_number()) {
        sendInfo.speed = jsonObject.at(SPEED_KEY).get<int>();
    }
    
    if (jsonObject.find(FILES_KEY) != jsonObject.end() && jsonObject.at(FILES_KEY).is_array()) {
        for (const auto& fileJson : jsonObject.at(FILES_KEY)) {
            FileInfo file;
            JsonToFileInfo(fileJson, file);
            sendInfo.files.push_back(file);
        }
    }
}

} // namespace FileShare
} // namespace OHOS
#endif // FILE_SHARE_JSON_UTIL_H    